home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Program : DATADISP (Main)
- Authors : W.E.R. Stroebel.
- Purpose : Displaying an unknown file in a "readable" way.
- Modules : None
- Compile : TCC, large model, enable stack checking.
- Created : June 29, 1989
- Edited : June 30, 1989
- - Small problem with labels fixed.
- - Unknowns > 16 bytes split.
-
- */
-
- #include <stdio.h>
- #include <conio.h>
- #include <stdlib.h>
- #include <alloc.h>
- #include <string.h>
- #include <ctype.h>
-
- enum types {
- UNKNOWN, ZSTR, FSTR, LSTR, UNS16, INT16, UNS32, INT32, FLOAT, DOUBLE
- };
-
- struct items {
- char label [4];
- enum types type;
- int len;
- } *item, ti;
-
- union data {
- char *s;
- unsigned u;
- int d;
- long unsigned lu;
- long ld;
- float e;
- double le;
- } d;
-
- FILE *df, *cf;
- int numdef, maxitem;
-
- void read_unknown (void)
- {
- int cnt;
- long siz, fsiz;
-
- fseek (df, 0, SEEK_END);
- fsiz = ftell (df);
- siz = 0;
- for (cnt = 0; siz < fsiz && cnt < maxitem; cnt ++) {
- item [cnt].type = UNKNOWN;
- if (fsiz - siz >= 16) {
- item [cnt].len = 16;
- siz += 16;
- } else {
- item [cnt].len = (int) (fsiz - siz);
- siz = fsiz;
- }
- }
- numdef = cnt;
- }
-
- void mputch (char c)
- {
- if (c > 31 && c != '\\') {
- putch (c);
- } else {
- switch (c) {
- case 0 : break;
- case '\n' : printf ("\\n"); break;
- case '\t' : printf ("\\t"); break;
- case '\v' : printf ("\\v"); break;
- case '\b' : printf ("\\b"); break;
- case '\r' : printf ("\\r"); break;
- case '\f' : printf ("\\f"); break;
- case '\a' : printf ("\\a"); break;
- case '\\' : printf ("\\\\"); break;
- default : printf ("\\x%02X", (unsigned char) c); break;
- }
- }
- }
-
- void display (int inum)
- {
- int cnt, c;
- long offset;
- char lab [5];
-
- offset = 0;
- lab [4] = 0;
- for (cnt = 0; cnt < inum; cnt ++) offset += item [cnt].len;
- fseek (df, offset, SEEK_SET);
- while (wherey () < 22 && cnt < numdef) {
- if (item [cnt].label [0] == 0) {
- printf ("%4u ", cnt);
- } else {
- memcpy (lab, item [cnt].label, 4);
- printf ("%4s ", lab);
- }
- switch (item [cnt].type) {
- case ZSTR :
- printf ("Z%2d:", item [cnt].len);
- d.s = (char *) malloc (item [cnt].len);
- fread (d.s, item [cnt].len, 1, df);
- putch ('"');
- for (c = 0; d.s [c] != 0; c ++) {
- mputch (d.s [c]);
- }
- printf ("\"\n");
- free (d.s);
- break;
- case FSTR :
- printf ("F%2d:", item [cnt].len);
- d.s = (char *) malloc (item [cnt].len);
- fread (d.s, item [cnt].len, 1, df);
- putch ('"');
- for (c = 0; c < item [cnt].len; c ++) {
- mputch (d.s [c]);
- }
- printf ("\"\n");
- free (d.s);
- break;
- case LSTR :
- d.s = (char *) malloc (item [cnt].len);
- fread (d.s, item [cnt].len, 1, df);
- printf ("L%2d:", d.s [0]);
- putch ('"');
- for (c = 1; c <= d.s [0]; c ++) {
- mputch (d.s [c]);
- }
- printf ("\"\n");
- free (d.s);
- break;
- case UNS16 :
- printf ("W%2d:", item [cnt].len);
- fread (&d.u, item [cnt].len, 1, df);
- printf ("%5u (%04X)\n", d.u, d.u);
- break;
- case INT16 :
- printf ("I%2d:", item [cnt].len);
- fread (&d.d, item [cnt].len, 1, df);
- printf ("%5d (%04X)\n", d.d, d.d);
- break;
- case UNS32 :
- printf ("D%2d:", item [cnt].len);
- fread (&d.lu, item [cnt].len, 1, df);
- printf ("%5lu (%08X)\n", d.lu, d.lu);
- break;
- case INT32 :
- printf ("L%2d:", item [cnt].len);
- fread (&d.ld, item [cnt].len, 1, df);
- printf ("%5ld (%08X)\n", d.ld, d.ld);
- break;
- case FLOAT :
- printf ("R%2d:", item [cnt].len);
- fread (&d.e, item [cnt].len, 1, df);
- printf ("%E\n", d.e);
- break;
- case DOUBLE :
- printf ("D%2d:", item [cnt].len);
- fread (&d.le, item [cnt].len, 1, df);
- printf ("%lE\n", d.le);
- break;
- default :
- printf ("U%2d:", item [cnt].len);
- d.s = (char *) malloc (item [cnt].len);
- fread (d.s, item [cnt].len, 1, df);
- for (c = 0; c < item [cnt].len; c ++) {
- printf ("%02X ", (unsigned char) d.s [c]);
- }
- gotoxy (64, wherey ());
- for (c = 0; c < item [cnt].len; c ++) {
- printf ("%c", d.s [c] > 31 ? d.s [c] : '.');
- }
- if (wherex () != 1) printf ("\n");
- free (d.s);
- break;
- }
- cnt ++;
- }
- }
-
- void delete (int inum)
- {
- int c;
-
- for (c = inum; c < numdef - 1; c ++) {
- item [c] = item [c + 1];
- }
- numdef --;
- }
-
- void insert (int inum, struct items *i)
- {
- int c;
-
- for (c = numdef; c > inum; c --) {
- item [c] = item [c - 1];
- }
- item [inum] = *i;
- if (numdef < maxitem) numdef ++;
- }
-
- void cleanup (void)
- {
- int cnt;
- long siz, fsiz;
- struct items t;
-
- fseek (df, 0, SEEK_END);
- fsiz = ftell (df);
- siz = 0;
- for (cnt = 0; siz < fsiz && cnt < maxitem; cnt ++) {
- if (item [cnt].type == UNKNOWN && item [cnt].len > 16) {
- t.type = UNKNOWN;
- t.len = item [cnt].len - 16;
- t.label [0] = 0;
- insert (cnt + 1, &t);
- item [cnt].len = 16;
- siz += 16;
- } else {
- siz += item [cnt].len;
- }
- }
- numdef = cnt;
- if (siz > fsiz) { /* last item is to big (and at least 2 bytes long) */
- item [numdef - 1].len -= (int) (siz - fsiz);
- if (item [numdef - 1].type != UNKNOWN) {
- item [numdef - 1].type = UNKNOWN; /* regardless : wrong size ! */
- }
- }
- }
-
- void add_item (int inum, struct items *i)
- {
- struct items t;
-
- while (item [inum].len < i->len) {
- item [inum].len += item [inum + 1].len;
- delete (inum + 1);
- }
- if (item [inum].len > i->len) {
- t.type = UNKNOWN;
- t.len = item [inum].len - i->len;
- t.label [0] = 0;
- insert (inum + 1, &t);
- item [inum] = *i;
- } else {
- item [inum].type = i->type;
- }
- /* cleanup : break up unknowns > 16 bytes, check file size */
- cleanup ();
- }
-
- void fixed_records (int fnum, int lnum)
- {
- int cnt, des;
- long siz, fsiz;
-
- lnum ++;
- des = lnum;
- fseek (df, 0, SEEK_END);
- fsiz = ftell (df);
- siz = 0;
- for (cnt = 0; cnt < lnum; cnt ++) { /* header and first record size */
- siz += item [cnt].len;
- }
- while (siz < fsiz && cnt < maxitem) {
- for (cnt = fnum; cnt < lnum; cnt ++) {
- item [des] = item [cnt];
- siz += item [cnt].len;
- des ++;
- }
- }
- numdef = des;
- cleanup (); /* in case user messed up defining record */
- }
-
- main (int argn, char *argv [])
- {
- int ch, inum, lnum, c2;
- char s [80];
-
- clrscr ();
- printf ("DATADISP - General datafile display program.\n\n");
- if (argn < 2 || argn > 3 || strchr (argv [1], '?') != NULL) {
- printf ("USAGE : DATADISP datafile <infofile>\n");
- exit (1);
- }
- if ((df = fopen (argv [1], "rb")) == NULL) {
- perror (argv [1]);
- exit (1);
- }
- printf ("Opened data file : %s\n", argv [1]);
- maxitem = 65000 / sizeof (struct items);
- item = (struct items *) malloc (maxitem * sizeof (struct items));
- memset (item, 0, maxitem * sizeof (struct items));
- memset (&ti, 0, sizeof (ti));
- if (argn == 3) {
- printf ("Opened info file : %s", argv [2]);
- if ((cf = fopen (argv [2], "rb")) == NULL) {
- numdef = 0;
- if ((cf = fopen (argv [2], "wb")) == NULL) {
- perror (argv [2]);
- exit (1);
- }
- } else {
- numdef = fread (item, sizeof (struct items), maxitem, cf);
- }
- printf (" - Read %d item descriptors.\n", numdef);
- fclose (cf);
- unlink (argv [2]);
- cf = fopen (argv [2], "wb");
- } else {
- cf = NULL;
- }
- if (numdef == 0) {
- read_unknown ();
- }
- inum = 0;
- printf ("Hit any key to start : ");
- getch ();
- do {
- window (1, 1, 80, 22);
- clrscr ();
- display (inum);
- window (1, 23, 80, 25);
- clrscr ();
- printf ("----------------------------------------");
- printf ("----------------------------------------");
- printf ("ITEM : Add, Remove, Display, Label. Fixed. Quit : ");
- ch = getch ();
- ch = toupper (ch);
- switch (ch) {
- case 'A' :
- gotoxy (1, 2);
- clreol ();
- printf ("Enter item number : ");
- scanf ("%d", &inum);
- if (inum < numdef) {
- gotoxy (1, 2);
- clreol ();
- printf ("TYPE : Unknown, String, Decimal, Real. Quit : ");
- c2 = getch ();
- c2 = toupper (c2);
- switch (c2) {
- case 'U' : ti.type = UNKNOWN; break;
- case 'S' :
- gotoxy (1, 2);
- clreol ();
- printf ("STRING : Fixed, Asciiz, Length. Quit : ");
- c2 = getch ();
- c2 = toupper (c2);
- switch (c2) {
- case 'F' : ti.type = FSTR; break;
- case 'A' : ti.type = ZSTR; break;
- case 'L' : ti.type = LSTR; c2 = 'T'; break;
- default : c2 = 'Q';
- }
- break;
- case 'D' :
- gotoxy (1, 2);
- clreol ();
- printf ("DECIMAL : Word, Int, Dword, Long. Quit : ");
- c2 = getch ();
- c2 = toupper (c2);
- switch (c2) {
- case 'W' : ti.type = UNS16; ti.len = 2; break;
- case 'I' : ti.type = INT16; ti.len = 2; break;
- case 'D' :
- ti.type = UNS32; ti.len = 4; c2 = 'X';
- break;
- case 'L' : ti.type = INT32; ti.len = 4; break;
- default : c2 = 'Q';
- }
- break;
- case 'R' :
- gotoxy (1, 2);
- clreol ();
- printf ("REAL : Single or Double precision. Quit : ");
- c2 = getch ();
- c2 = toupper (c2);
- switch (c2) {
- case 'S' :
- ti.type = FLOAT; ti.len = sizeof (float);
- break;
- case 'D' :
- ti.type = DOUBLE; ti.len = sizeof (double);
- break;
- default : c2 = 'Q';
- }
- break;
- }
- if (strchr ("UFAT", c2) != NULL) {
- gotoxy (1, 2);
- clreol ();
- printf ("Length : ");
- scanf ("%d", &(ti.len));
- }
- if (c2 != 'Q') add_item (inum, &ti);
- } else {
- inum = 0;
- }
- break;
- case 'R' :
- gotoxy (1, 2);
- clreol ();
- printf ("Enter item number : ");
- scanf ("%d", &inum);
- if (inum < numdef - 1) {
- item [inum].type = UNKNOWN;
- item [inum].len += item [inum + 1].len;
- delete (inum + 1);
- } else {
- inum = 0;
- }
- cleanup (); /* items > 16 bytes, filesize test */
- break;
- case 'D' :
- gotoxy (1, 2);
- clreol ();
- printf ("Enter item number : ");
- scanf ("%d", &inum);
- if (inum < numdef) {
- } else {
- inum = 0;
- }
- break;
- case 'L' :
- gotoxy (1, 2);
- clreol ();
- printf ("Enter item number : ");
- scanf ("%d", &inum);
- if (inum < numdef) {
- gotoxy (1, 2);
- clreol ();
- printf ("Enter item label (max 4 chars) : ");
- scanf ("%s", s);
- memcpy (item [inum].label, s, 4);
- } else {
- inum = 0;
- }
- break;
- case 'F' :
- gotoxy (1, 2);
- clreol ();
- printf ("Enter first item of fixed records : ");
- scanf ("%d", &inum);
- gotoxy (1, 2);
- clreol ();
- printf ("Enter last item of fixed records : ");
- scanf ("%d", &lnum);
- fixed_records (inum, lnum);
- break;
- }
- } while (ch != 'Q');
- fclose (df);
- if (cf != NULL) {
- fwrite (item, sizeof (struct items), numdef, cf);
- fclose (cf);
- }
- return 0;
- }
-